package com.hexiang.controller;

import com.hexiang.domain.ResultMap;
import com.hexiang.service.AsyncService;
import com.hexiang.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

@RestController
@Slf4j
public class AsyncController {

    private final Logger logger = LoggerFactory.getLogger(AsyncController.class);

    @Resource
    private AsyncService asyncService;

    @RequestMapping("async")
    public ResultMap async() {
        asyncService.async();
        return ResultMap.buildSuccess();
    }

    @RequestMapping("future")
    public ResultMap future() {
        Future<UserVO> task1 = asyncService.future1(new Random().nextLong());
        Future<UserVO> task2 = asyncService.future2(new Random().nextLong());
        Future<UserVO> task3 = asyncService.future3(new Random().nextLong());
        try {
            while (true) {
                // 判断是否所有异步执行完成
                if (task1.isDone() && task2.isDone() && task3.isDone()) {
                    // 三个任务都调用完成，退出循环等待
                    break;
                }
                Thread.sleep(100);
            }
            List<UserVO> list = new ArrayList<>();
            list.add(task1.get());
            list.add(task2.get());
            list.add(task3.get());
            return ResultMap.buildSuccess().put("list", list);
        } catch (InterruptedException e) {
            logger.error("interrupted exp", e);
        } catch (ExecutionException e) {
            logger.error("execution exp", e);
        }
        return ResultMap.buildFailed("执行失败");
    }

    @RequestMapping("batchGetUserInfoByFuture")
    public List<String> batchGetUserInfoByFuture(@RequestParam("userNames") List<String> userNameList) {
        long start = System.currentTimeMillis();
        List<Future<String>> userFutureList = userNameList.stream().map(userName -> asyncService.getUserInfoByFuture(userName)).collect(Collectors.toList());
        List<String> resultList = userFutureList.stream().map(future -> {
            try {
                return future.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            return null;
        }).collect(Collectors.toList());
        long end = System.currentTimeMillis();
        log.info("CompletableFuture耗时--》" + (end - start) + "ms");
        return resultList;
    }

    @RequestMapping("batchGetUserInfoByCompletableFuture")
    public List<String> batchGetUserInfoByCompletableFuture(@RequestParam("userNames") List<String> userNameList) {
        long start = System.currentTimeMillis();
        List<CompletableFuture<String>> userFutureList = userNameList.stream().map(userName -> asyncService.getUserInfoByCompletableFuture(userName)).collect(Collectors.toList());
        List<String> resultList = userFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList());
        long end = System.currentTimeMillis();
        log.info("CompletableFuture耗时--》" + (end - start) + "ms");
        return resultList;
    }
}
